home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / PC / ADA / ADATUTOR / ADA-TUTR.ADA < prev    next >
Text File  |  1988-03-25  |  14KB  |  243 lines

  1. -- ADA-TUTR.ADA   Ver. 1.00   25-MAR-1988
  2. -- Copyright 1988 John J. Herro
  3. -- Software Innovations Technology
  4. -- 1083 Mandarin Drive NE, Palm Bay, FL 32905-4706   (407)951-0233
  5. --
  6. -- Introduction:
  7. --
  8. -- ADA-TUTR provides interactive instruction in the Ada programming language,
  9. -- allowing the student to learn at his own pace.  On a PC, it requires a hard
  10. -- disk or a 3.5-inch disk.  Access to an Ada compiler is helpful, but not
  11. -- required.  The user can exit this program at any time by striking X (or
  12. -- control-BREAK), and later resume the session exactly where he left off.
  13. --
  14. -- ADA-TUTR presents a screenful of information at a time.  Screens are read
  15. -- in 64-byte blocks from the random access file ADA-TUTR.DAT, using DIRECT_IO.
  16. -- For most screens, ADA-TUTR waits for the user to strike one character to
  17. -- determine which screen to show next.  Screens are numbered starting with
  18. -- 101; each screen has a three-digit number.  Screens 101 through 106 have
  19. -- special uses, as follows:
  20. --
  21. -- 101 - This screen is presented when the user completes the Ada course.  It
  22. --       contains a congratulatory message.  After this screen is shown,
  23. --       control returns directly to the operating system; the program doesn't
  24. --       wait for the user to strike a character.
  25. -- 102 - This screen is presented when the user exits ADA-TUTR before
  26. --       completing the course.  It displays the number of the screen where the
  27. --       student left off, so he can later resume the session at the same
  28. --       place (see screen 105).  After this screen is shown, control returns
  29. --       directly to the operating system; the program doesn't wait for the
  30. --       user to strike a character.
  31. -- 103 - This screen is shown whenever the student strikes X or control-BREAK.
  32. --       It asks if the user wants to exit the program.  If he strikes Y,
  33. --       screen 102 is shown and control returns to the operating system.  If
  34. --       he types N (perhaps because he struck X in error), ADA-TUTR returns to
  35. --       the previous screen.  From screen 103, the student can also strike M
  36. --       to see the main menu (screen 106).
  37. -- 104 - This is the opening screen.  It asks if the student has used ADA-TUTR
  38. --       before.  If he strikes N, an introductory screen is presented and the
  39. --       course begins.  If he strikes Y, screen 105 is shown.
  40. -- 105 - This screen says "Welcome back!"  It then asks the user to type the
  41. --       number where he earlier left off (see screen 102).  For this screen,
  42. --       instead of striking one character, the user types a three-digit number
  43. --       and presses ENTER.  Any number from 104 through 596 (the highest
  44. --       possible screen number) is accepted.  That screen is then shown, so
  45. --       the student can resume learning where he left off.  If the user has
  46. --       forgotten the number, or if he wants to resume at some other place, he
  47. --       can request screen number 106 to see the main menu.  Also, if he types
  48. --       the number of a non-existent screen, screen 106 is shown.
  49. -- 106 - This screen contains the main menu of topics covered in ADA-TUTR.
  50. --       When the user selects a main topic, an appropriate sub-menu is shown.
  51. --
  52.  
  53. -- Format of the Data File:
  54. --
  55. -- ADA-TUTR.DAT is a random access file containing 64-byte blocks.  The first
  56. -- block is referred to as block 1.  Data for the screens are stored starting
  57. -- in block 32.  Blocks 1 through 31 contain the numbers of the starting blocks
  58. -- for each of the 496 possible screens (101 through 596).  Four bytes are
  59. -- allocated for each starting block number.  These numbers are stored in
  60. -- ASCII, and 1000 is added to each block number so that it will have exactly
  61. -- four digits.  For example, screen 101 starts at block 32, so the first four
  62. -- bytes of block 1 contain "1032" in ASCII.  The next four bytes refer to
  63. -- screen 102, etc.  Not all 496 possible screens exist.  For any unused
  64. -- screens, the starting block number of screen 106 (the main menu) is stored.
  65. --
  66. -- The first 64-byte block of each screen is a "control block."  Thus, block
  67. -- 32 of ADA-TUTR.DAT is the control block for screen 101.  The control block
  68. -- is followed by enough 64-byte blocks to contain the text for that screen.
  69. --
  70. -- The first two bytes of the control block contain, in ASCII, the number of
  71. -- text blocks that follow.  A constant 10 is added to this number so that it
  72. -- will always have exactly two digits.  The next two bytes contain, in ASCII,
  73. -- the number of significant text characters in the last 64-byte block, plus
  74. -- ten.  This number can range from 11 to 74.  For example, if a screen has 130
  75. -- characters, three text blocks will be needed, and the last block will have
  76. -- two significant characters.  Thus, the first four bytes of the control block
  77. -- will contain "1312" in ASCII.
  78. --
  79. -- Starting with byte 5, the control block contains a list of characters that
  80. -- the user might strike after seeing this screen.  Each character is followed
  81. -- by the three-digit number of the next screen to be shown when that character
  82. -- is struck.  The list is terminated by $.  There is enough room for 14
  83. -- characters and screen numbers, and the terminating $, with three bytes to
  84. -- spare.  For example, in the control block for screen 104, bytes 5 through 13
  85. -- might contain "Y105N118$".  This means that, if the user strikes Y, screen
  86. -- 105 will be shown, and if he strikes N, screen 118 will be shown.  Striking
  87. -- any other character will simply cause a beep (except that CR will be
  88. -- ignored).  A "screen number" of 100 following a character simply means "go
  89. -- back to the previous screen."  This feature is used in screen 103.
  90. --
  91. -- If the list of characters begins with '#', the user is prompted to type the
  92. -- next screen number.  This feature is used in screen 105.
  93. --
  94.  
  95. -- Before Running ADA-TUTR on a PC:
  96. --
  97. -- ADA-TUTR uses ANSI escape sequences for highlighting, cursor positioning,
  98. -- and reverse video.  Therefore, on a PC the device driver ANSI.SYS must be
  99. -- installed before ADA-TUTR will work correctly.  To install ANSI.SYS, do the
  100. -- following:
  101. --
  102. -- 1.  If there is a file CONFIG.SYS in the root directory of the disk from
  103. --     which you boot, type it and look for a line saying "DEVICE=ANSI.SYS"
  104. --     (without the quotes), in either upper or lower case.  If that line is
  105. --     not present, add it to CONFIG.SYS anywhere in the file, using an
  106. --     ordinary text editor or word processor in the non-document mode.  If
  107. --     there is no CONFIG.SYS file, create one containing the single line
  108. --     "DEVICE=ANSI.SYS" (without the quotes).
  109. --
  110. -- 2.  If there is no file ANSI.SYS in your root directory, copy ANSI.SYS from
  111. --     from your system distribution diskette to the root directory of the disk
  112. --     from which you boot.
  113. --
  114. -- 3.  Reboot the computer.  ADA-TUTR should then work correctly.
  115. --
  116. --
  117. --
  118. --
  119. -- Note:  This program is compiled with version 1.30 Beta of Artek Ada (tm,
  120. --        Artek Corp.)  Due to minor bugs in that beta-test version, the form
  121. --        feeds must be removed from a copy of this file before compilation.
  122. --        Also, the two subprograms cannot be made separate, which would have
  123. --        been preferred.
  124. --
  125. --
  126. --
  127.  
  128. with QGET, CON_IO, DIRECT_IO; use CON_IO;
  129.    -- The procedure QGET and the package CON_IO (console I/O) come with Artek
  130.    -- Ada.  QGET gets one character from the keyboard.  CON_IO contains PUT,
  131.    -- PUT_LINE, and NEW_LINE, similar to TEXT_IO.  It also contains GET to get
  132.    -- a string (with editing capability), and CLS to clear the screen.
  133. procedure ADA_TUTR is
  134.    subtype BLOCK_SUBTYPE is STRING(1 .. 64);
  135.    package RANDOM_IO is new DIRECT_IO(BLOCK_SUBTYPE); use RANDOM_IO;
  136.    DATA_FILE         : FILE_TYPE;      -- The file from which screens are read.
  137.    BLOCK,                               -- A 64-byte block read from data file.
  138.    CONTROL_BLOCK     : BLOCK_SUBTYPE;  -- Control info. for the current screen.
  139.    PLACE,                                -- Index to search list of characters.
  140.    WHERE,                              -- Location of ctrl. block in data file.
  141.    NUM_OF_BLOCKS,                       -- # of blocks of text for this screen.
  142.    LEN_OF_LAST_BLOCK : INTEGER;           -- # of signif. chars. in last block.
  143.    SN, OLD_SN        : INTEGER := 104;     -- Screen #.  Opening screen is 104.
  144.    INDX              : STRING(1 .. 1984);    -- Starting block numbers, + 1000.
  145.    INPUT             : STRING(1 .. 4);              -- Input typed by the user.
  146.    OK                : BOOLEAN;            -- True when user response is valid.
  147.    LEGAL_NOTE        : constant STRING(1 .. 30) :=
  148.         " Copyright 1988 John J. Herro ";
  149.                          -- LEGAL_NOTE isn't used by the program, but it causes
  150.                          -- the compiler to place this string in the .EXE file.
  151.  
  152.    procedure USER_TYPES_NEXT_SCREEN_NUMBER is
  153.    begin
  154.       OK := FALSE;
  155.       while not OK loop            -- Keep trying until user response is valid.
  156.          PUT("# ");                       -- Prompt user to type screen number.
  157.          INPUT := "    ";  GET(INPUT);  NEW_LINE; -- Get screen num. from user.
  158.          if INPUT(1) = 'x' or INPUT(1) = 'X' or INPUT(1) = ASCII.ETX then
  159.             SN := 103;             -- Show screen 103 if user types X or BREAK.
  160.             OK := TRUE;                      -- X or BREAK is a valid response.
  161.          else
  162.             begin                            -- Convert ASCII input to screen
  163.                SN := INTEGER'VALUE(INPUT);   -- number.  If in range, set OK to
  164.                OK := SN in 104 .. 596;       -- TRUE.  If input could not be
  165.             exception                        -- converted to a number (e.g.,
  166.                when others => null;          -- illegal character), leave OK =
  167.             end;                             -- FALSE so user can try again.
  168.          end if;
  169.          if not OK then
  170.             PUT_LINE("Incorrect number.  Please try again.");
  171.          end if;
  172.       end loop;
  173.    end USER_TYPES_NEXT_SCREEN_NUMBER;
  174.  
  175.    procedure USER_TYPES_ONE_CHARACTER is
  176.    begin
  177.       PUT(">");                         -- Prompt user to strike one character.
  178.       OK := FALSE;
  179.       while not OK loop            -- Keep trying until user response is valid.
  180.          QGET(INPUT(1));                        -- Get one character from user.
  181.          if INPUT(1) in 'a' .. 'z' then        -- Force upper case to simplify.
  182.             INPUT(1) := CHARACTER'VAL(CHARACTER'POS(INPUT(1)) - 32);
  183.          end if;
  184.          if INPUT(1) = 'X' or INPUT(1) = ASCII.ETX then
  185.             SN := 103;             -- Show screen 103 if user types X or BREAK.
  186.             OK := TRUE;                      -- X or BREAK is a valid response.
  187.          end if;
  188.          PLACE := 5;        -- Search list of valid characters for this screen.
  189.          while not OK and CONTROL_BLOCK(PLACE) /= '$' loop  -- $ ends the list.
  190.             if INPUT(1) = CONTROL_BLOCK(PLACE) then
  191.                  -- Typed char. found in list; get screen # from control block.
  192.                SN := INTEGER'VALUE(CONTROL_BLOCK(PLACE + 1 .. PLACE + 3));
  193.                OK := TRUE;   -- Characters in the list are all valid responses.
  194.             end if;
  195.             PLACE := PLACE + 4; -- A 3-digit number follows each char. in list.
  196.          end loop;
  197.          if not OK and INPUT(1) /= ASCII.CR then         -- Beep if response is
  198.             PUT(ASCII.BEL);                              -- not valid, but
  199.          end if;                                         -- ignore CRs quietly.
  200.       end loop;
  201.    end USER_TYPES_ONE_CHARACTER;
  202.  
  203. begin
  204.    OPEN(DATA_FILE, MODE => IN_FILE, NAME => "ADA-TUTR.DAT");
  205.    for I in 1 .. 31 loop                -- Read list of starting block numbers.
  206.       READ(DATA_FILE, ITEM => BLOCK, FROM => COUNT(I));
  207.       INDX(64*I - 63 .. 64*I) := BLOCK;
  208.    end loop;
  209.    while OLD_SN >= 103 loop    -- Exit program after showing screen 101 or 102.
  210.       WHERE := INTEGER'VALUE(INDX(SN*4 - 403 .. SN*4 - 400)) - 1000;
  211.                                  -- Get location of control block in data file.
  212.       READ(DATA_FILE, ITEM => CONTROL_BLOCK, FROM => COUNT(WHERE));
  213.       NUM_OF_BLOCKS := INTEGER'VALUE(CONTROL_BLOCK(1 .. 2)) - 10;
  214.       LEN_OF_LAST_BLOCK := INTEGER'VALUE(CONTROL_BLOCK(3 .. 4)) - 10;
  215.       CLS;                           -- Clear the display and show this screen.
  216.       for I in 1 .. NUM_OF_BLOCKS - 1 loop
  217.          READ(DATA_FILE, ITEM => BLOCK, FROM => COUNT(WHERE + I));
  218.          if SN = 102 and I = 3 then  -- Screen 102 needs # where user left off.
  219.             BLOCK(35 .. 38) := INTEGER'IMAGE(OLD_SN);
  220.          end if;
  221.          PUT(BLOCK);
  222.       end loop;
  223.       READ(DATA_FILE, ITEM => BLOCK, FROM => COUNT(WHERE + NUM_OF_BLOCKS));
  224.       PUT(BLOCK(1 .. LEN_OF_LAST_BLOCK));  -- Show only significant characters.
  225.       if SN /= 103 then      -- Screen 103 means user typed X or BREAK to exit.
  226.          OLD_SN := SN;       -- Save any other screen number, so user can go
  227.       end if;                -- back to it from 103.  Don't go "back" to 103!
  228.       if SN >= 103 then              -- If this screen doesn't end the program,
  229.          if CONTROL_BLOCK(5) = '#' then      -- set SN to # of the next screen.
  230.             USER_TYPES_NEXT_SCREEN_NUMBER;
  231.          else
  232.             USER_TYPES_ONE_CHARACTER;
  233.          end if;
  234.       end if;
  235.       if SN = 100 then -- Screen number "100" means go back to the last screen.
  236.          SN := OLD_SN;
  237.       end if;
  238.    end loop;
  239. exception
  240.    when NAME_ERROR =>
  241.       PUT_LINE("I'm sorry.  The file ADA-TUTR.DAT seems to be missing.");
  242. end ADA_TUTR;
  243.